using Launcher;
using Serilog;
using System.CommandLine;
using System.IO;

internal class Program
{
    static async Task Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .Enrich.FromLogContext()
#if RELEASE
            .MinimumLevel.Information()
#else
            .MinimumLevel.Debug()
            .WriteTo.Console()
#endif
            .WriteTo.File(
                path: $"logs/launcher/log-.txt",
                rollingInterval: RollingInterval.Day,
                rollOnFileSizeLimit: true,
                retainedFileCountLimit: 7,
                outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}",
                fileSizeLimitBytes: 10 * 1024 * 1024
            )
            .CreateLogger();

        var logger = Log.Logger;

        try
        {
            logger.Information("应用程序启动");

            var rootCommand = new RootCommand();
            var fileOption = new Option<string>("--config", new string[] { "-f" });
            rootCommand.Options.Add(fileOption);
            var result = rootCommand.Parse(args);
            var configPath = result.GetValue(fileOption);

            if (string.IsNullOrWhiteSpace(configPath))
            {
                configPath = LauncherHelper.GetDefaultConfigPath();
            }
            else
            {
                configPath = Path.GetFullPath(configPath);
                var jsonExtension = Path.GetExtension(configPath);

                if (!string.Equals(jsonExtension, ".json", StringComparison.OrdinalIgnoreCase))
                {
                    logger.Error("配置文件必须是 .json 格式");
                    return;
                }
            }

            // 加载配置
            var parameters = LauncherHelper.LoadAssemblyLoaderParameters(configPath);

            if (!parameters.Any())
            {
                logger.Warning("配置文件中没有有效的加载参数");
                return;
            }

            logger.Information($"找到 {parameters.Count()} 个插件配置");

            // 并行执行插件
            var options = new ParallelOptions
            {
                MaxDegreeOfParallelism = Environment.ProcessorCount // 限制并行度
            };

            await Parallel.ForEachAsync(parameters, options, async (parameter, cancellationToken) =>
            {
                try
                {
                    logger.Information("正在加载插件: {FullName}", parameter.EntryAssemblyFile);

                    var context = new DynamicAssemblyLoadContext(parameter);
                    await context.ExecuteAsync();

                    logger.Information($"插件 {parameter.EntryAssemblyFile} 执行完成");
                }
                catch (Exception ex)
                {
                    logger.Error(ex, $"加载或执行插件 {parameter.EntryAssemblyFile} 时出错");
                }
            });

            logger.Information("所有插件执行完成");
        }
        catch (Exception ex)
        {
            logger.Fatal(ex, "应用程序发生致命错误");
            Environment.Exit(1);
        }
        finally
        {
            await Log.CloseAndFlushAsync();
        }
    }
}